home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / orig / reloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-10  |  2.8 KB  |  103 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4.  
  5. typedef unsigned char byte;
  6. typedef unsigned int word;
  7.  
  8. byte Nib(int X) {
  9.    if (X >= '0' && X <= '9') return X - '0';
  10.    if (X >= 'a' && X <= 'f') return X - 'a' + 10;
  11.    if (X >= 'A' && X <= 'F') return X - 'A' + 10;
  12.    fprintf(stderr, "Bad hexadecimal digit in input\n");
  13.    exit(1);
  14. }
  15.  
  16. byte CheckSum;
  17. byte GetHex(FILE *InF) {
  18.    int A, B; byte Bt;
  19.    A = fgetc(InF); B = fgetc(InF);
  20.    if (A == EOF || B == EOF) {
  21.       fprintf(stderr, "Unexpected EOF.\n"); exit(1);
  22.    }
  23.    Bt = Nib(A) << 4 | Nib(B);
  24.    CheckSum = (CheckSum + Bt)&0xff; return Bt;
  25. }
  26.  
  27. word GetWord(FILE *InF) {
  28.    word A, B;
  29.    A = GetHex(InF); B = GetHex(InF);
  30.    return (A << 8) | B;
  31. }
  32.  
  33. void PutHex(FILE *OutF, byte Ch) {
  34.    fprintf(OutF, "%02x", Ch); CheckSum = (CheckSum + Ch)&0xff;
  35. }
  36.  
  37. void PutWord(FILE *OutF, word W) {
  38.    PutHex(OutF, (byte)(W >> 8)); PutHex(OutF, (byte)(W&0xff));
  39. }
  40.  
  41. void Relocate(word Offset, FILE *InF, FILE *OutF) {
  42.    int Ch, I;
  43.    byte Size, Mark; word Addr;
  44.    byte Buffer[0x10];
  45.    while (1) {
  46.       do {
  47.          Ch = fgetc(InF);
  48.          if (Ch == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); }
  49.       } while (Ch != ':');
  50.       CheckSum = 0;
  51.       Size = GetHex(InF); Addr = GetWord(InF) + Offset; Mark = GetHex(InF);
  52.       for (I = 0; I < Size; I++) Buffer[I] = GetHex(InF);
  53.       (void)GetHex(InF); (void)fgetc(InF);
  54.       if (CheckSum != 0) {
  55.          fprintf(stderr, "Bad checksum.\n"); exit(1);
  56.       }
  57.       fputc(':', OutF);
  58.       CheckSum = 0;
  59.       PutHex(OutF, Size); PutWord(OutF, Addr); PutHex(OutF, Mark);
  60.       for (I = 0; I < Size; I++) PutHex(OutF, Buffer[I]);
  61.       PutHex(OutF, (byte)-CheckSum);
  62.       fputc('\n', OutF);
  63.       if (Mark) break;
  64.    }
  65. }
  66.  
  67. word atoh(char *S) {
  68.    word Val;
  69.    for (Val = 0; *S != '\0'; S++) {
  70.       if (isdigit(*S)) Val = (Val << 4) | (*S - '0');
  71.       else if (isxdigit(*S)) Val = (Val << 4) | (tolower(*S) - 'a' + 10);
  72.       else return 0;
  73.    }
  74.    return Val;
  75. }
  76.  
  77. char *Convert(char *Path) {
  78.    static char *S; char *T;
  79.    S = (char *)malloc(strlen(Path) + 1);
  80.    if (S == 0) return 0;
  81.    strcpy(S, Path);
  82.    for (T = S + strlen(S); T > S; T--)
  83.       if (T[-1] == '.') break;
  84.    if (T == S) { free(S); return 0; }
  85.    *T++ = 'h', *T++ = 'x', *T = '\0';
  86.    return S;
  87. }
  88.  
  89. main(int ArgC, char **ArgV) {
  90.    word Offset; FILE *InF, *OutF; char *OutName;
  91.    if (ArgC != 3) { printf("Usage: relocate Offset Input.\n"); exit(0); }
  92.    Offset = atoh(ArgV[1]);
  93.    if (Offset == 0) printf("Zero offset/bad offset specified.\n");
  94.    OutName = Convert(ArgV[2]);
  95.    if (OutName == 0) { printf("%s not of form *.hex.\n", ArgV[2]); exit(0); }
  96.    InF = fopen(ArgV[2], "r");
  97.    if (InF == 0) { printf("Cannot open %s.\n", ArgV[2]); exit(0); }
  98.    OutF = fopen(OutName, "w");
  99.    if (OutF == 0) { printf("Cannot open %s.\n", OutName); exit(0); }
  100.    Relocate(Offset, InF, OutF);
  101.    fclose(InF), fclose(OutF);
  102. }
  103.